class ListNode {
  /**
   * @param {*} data 此节点存放的数据
   * @param {*} next 此节点下一个节点的引用地址
   */
  constructor(data,next) {
    this.data = data;
    this.next = next;
  }
}


class List {
  constructor() {
    //head指向第一个节点
    this.head = null;
    //节点数量
    this.size = 0;
  }

  /**
   *
   * @param index
   * @param listNode
   */
  add(index, listNode){
    debugger
    //如果要插入的索引为0, 即插到头首
    if (index === 0) {
      //如果已经有串了 需要先把这个已有的串 串在我们当前要插入的节点的后面
      listNode.next = this.head;
      //然后再把头结点指定为当前要插入的节点
      this.head = listNode;

    //
    } else {
      //获取要插入的节点的前一个节点
      let prev = this.get(index - 1);
      //先把之前有的串在我们要插入的节点的后面
      listNode.next = prev.next;
      //再把我们要插入的节点连到prev的后面
      prev.next = listNode;
    }

    //长度加1
    this.size++;
  }

  /**
   * 获取指定索引的结点对象
   * @param {number} index
   */
  get(index){
    this.rangeCheck(index);
    //先指向头结点
    let curr = this.head;
    //索引为几就往后走几步
    while (index--) {
      curr = curr.next;
    }
    return curr;
  }

  /**
   * 删除索引入对应的结点
   * @param {number} index
   */
  remove(index) {
    this.rangeCheck(index);
    if (index === 0) {
      this.head = this.head.next;
    } else {
      let prev = this.get(index - 1);
      prev.next = prev.next.next;
    }
    this.size--;
  }

  /**
   * 打印所有节点的数据
   */
  print() {
    //先让当前指针指向头指针
    let curr = this.head;
    let str = '';
    while (curr) {
      console.log('curr:',curr);
      //拼上当前的数据域
      str += curr.data + '->';
      //让当前指针指向下一个结点
      curr = curr.next;
    }
    str += 'null';
    console.log(str);
  }

  /**
   * 判断要获取的索引是否越界
   * @param {number} index
   */
  rangeCheck(index) {
    if (index < 0 || index >= this.size) {
      throw new Error('索引越界');
    }
  }
}


let list = new List();
//添加a结点
let a = new ListNode('A');
list.add(0, a);
//添加c结点
let c = new ListNode('C');
list.add(1, c);
//添加b节点
let b = new ListNode('B');
list.add(1, b);
//删除b节点
list.remove(1);
//头部添加d节点
let d = new ListNode('D');
list.add(0, d);
debugger
//打印所有节点
list.print();//D->A->C->null
